package com.xxwy.ddu.common.autowired.config;

import com.alibaba.druid.sql.visitor.functions.Lpad;
import com.xxwy.ddu.common.exception.BaseException;
import com.xxwy.ddu.common.exception.HttpCode;
import com.xxwy.ddu.common.exception.IllegalParameterException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 异常类的配置
 *
 * @author xxwy
 * on 2018/7/30 0030
 */
@ControllerAdvice
public class ExceptionConfig {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionConfig.class);


    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
    public ResponseEntity<ModelMap> getExceptionInfo(HttpServletRequest request, HttpServletResponse response,
                                                     Exception ex) {
        logger.info(request.getRequestURL() + " error==>{}", ex.getMessage());
        //1 参数校验异常（需要从绑定结果里面取出异常以及异常信息）
        BindingResult bindingResult = ((MethodArgumentNotValidException) ex).getBindingResult();
        ModelMap modelMap = new ModelMap();
        Map<String,String> msg = new HashMap<>();
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            for (FieldError fieldError : list) {
                msg.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
        }
        modelMap.put("code",HttpCode.BAD_REQUEST);
        modelMap.put("error",msg);
        modelMap.put("timestamp", System.currentTimeMillis());
        modelMap.put("path",request.getRequestURL());
        return ResponseEntity.ok(modelMap);
    }



    /**
     * 异常处理
     */
    @ResponseBody
    @ExceptionHandler(Exception.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<ModelMap> exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {

        ModelMap modelMap = new ModelMap();
        if (ex instanceof BaseException) {
            ((BaseException) ex).handler(modelMap);
        } else if (ex instanceof IllegalArgumentException) {
            new IllegalParameterException(ex.getMessage()).handler(modelMap);
        } else if (ex instanceof AuthenticationException) {
            if (ex.getMessage() != null) {
                modelMap.put("msg", ex.getMessage());
            } else {
                modelMap.put("msg", HttpCode.msg(HttpCode.LOGIN_FAIL));
            }
            modelMap.put("code", HttpCode.LOGIN_FAIL.toString());
        } //错误请求
        else if (ex.getClass().getName().startsWith("org.springframework")) {
            modelMap.put("code", HttpCode.BAD_REQUEST.toString());
            String msg = StringUtils.defaultIfBlank(ex.getMessage(), HttpCode.msg(HttpCode.INTERNAL_SERVER_ERROR));
            modelMap.put("msg", msg);
        } else {
            logger.error("系统错误：");
            ex.printStackTrace();
            modelMap.put("code", HttpCode.INTERNAL_SERVER_ERROR.toString());
            String msg = StringUtils.defaultIfBlank(ex.getMessage(), HttpCode.msg(HttpCode.INTERNAL_SERVER_ERROR));
            modelMap.put("msg", msg.length() > 150 ? "Ծ‸Ծ，我迷路了" : msg);
        }
        modelMap.put("timestamp", System.currentTimeMillis());
        modelMap.put("path",request.getRequestURL());
        return ResponseEntity.ok(modelMap);
    }


}
